home *** CD-ROM | disk | FTP | other *** search
/ NeXTSTEP 3.3 (Developer)…68k, x86, SPARC, PA-RISC] / NeXTSTEP 3.3 Dev Intel.iso / NextDeveloper / Headers / objc / typedstream.h < prev    next >
Text File  |  1993-03-11  |  11KB  |  200 lines

  1. /*
  2.     typedstream.h
  3.     Copyright 1989 NeXT, Inc.
  4. */
  5.  
  6. #ifndef _OBJC_TYPEDSTREAM_H_
  7. #define _OBJC_TYPEDSTREAM_H_
  8.  
  9. /*
  10.  *    This modules saves data structures for later retrieval.  You can use typedstreams to save arbitrary C data, including Objective C objects, onto an arbitrary stream (see \fBNXStream\fR), such as a file, memory buffer, or pasteboard buffer.  The process of saving data is calling archiving, the process of retrieving the data unarchiving.
  11.  *
  12.  *    Not only data structures are written, but also their type, allowing for retrieval even in the absence of the code used for saving them.  Objective C objects are stored along with the full class hierarchy, allowing for translation of old classes into new classes.
  13.  *    At writing time, a tight encoding is possible, because all the type information is present.  The encoding is not too tight, to allow for fast reading.  A check is done when reading data to confirm conformance of the stored data to the expected data.
  14.  *    Any Objective C class can define its own write: and read: methods.  By default, nothing is saved. 
  15.  *    Three types of versions are supported to allow for code evolution, not revolutions: typedstream versioning (used by the implementation), system versioning (used by NeXT), per class versioning (available for clients).
  16.  *    Shared objects as well as shared C pointers remain shared after reading.
  17.  *    Data structures to be saved can be carved at the level of their backpointers.
  18.  *
  19.  */
  20.   
  21.  
  22. #import <streams/streams.h>
  23. #import <objc/objc.h>
  24. #import <objc/zone.h>
  25.  
  26. typedef void NXTypedStream;    /* NXTypedStream is made opaque */
  27.  
  28.  
  29. /***********************************************************************
  30.  *    Creation, destruction and other global operations
  31.  **********************************************************************/
  32.  
  33. /*
  34.  *    When dealing with streams, it is important to keep in mind that the creator of a stream is responsible for destroying it after destroying the NXTypedStream.  In particular, NXTypedStreams do not destroy the underlying stream when they are closed, and only the NXTypedStream data structure is released.  One exception to this scheme, however, has been provided for convenience with NXOpenTypedStreamForFile.
  35.  *
  36.  */
  37.  
  38. extern NXTypedStream *NXOpenTypedStream (NXStream *physical, int mode);
  39.     /* If mode is NX_WRITEONLY, creates a NXTypedStream, ready for writing, given a physical stream on which to actually put the bytes. If mode is NX_READONLY, creates a NXTypedStream, ready for reading, given a physical stream on which to actually get the bytes.  The caller is responsible for closing physical.  If the file format mismatches right from the start with typedstream format, NULL is returned, otherwise an exception might be raised.  */
  40.     
  41. extern void NXSetTypedStreamZone(NXTypedStream *stream, NXZone *zone);
  42. extern NXZone *NXGetTypedStreamZone(NXTypedStream *stream);
  43.  
  44. extern BOOL NXEndOfTypedStream (NXTypedStream *stream);
  45.     /* For a stream opened for reading indicates whether or not more data follows. */
  46.  
  47. extern void NXFlushTypedStream (NXTypedStream *stream);
  48.     /* For a stream opened for writing, flushes the underlying physical stream. */
  49.  
  50. extern void NXCloseTypedStream (NXTypedStream *stream);
  51.     /* Flushes underlying stream and frees stream data structures.  Physical stream is not destroyed, except if stream was created with NXOpenTypedStreamForFile.  */
  52.  
  53.  
  54. /***********************************************************************
  55.  *    Writing and reading arbitrary data
  56.  **********************************************************************/
  57.  
  58. /*
  59.  *    The type of the data written follows the Objective C type string conventions <<Refer to Obj C documentation>>.  Supported descriptors:
  60.  *        'c': char
  61.  *        's': short
  62.  *        'i': int
  63.  *        'f': float
  64.  *        'd': double
  65.  *        '@': id
  66.  *        '*': char *
  67.  *        '%': NXAtom
  68.  *        ':': SEL
  69.  *        '#': Class
  70.  *        '!': int ignored
  71.  *        {<type>} : struct
  72.  *        [<count><itemType>] : array
  73.  *
  74.  *    Example, "{csi*@}" means a struct containing a char, a short, an int, a string and an object.  Type descriptor '%' implies at read time that the string is uniqued (using \fBNXUniqueString()\fR).
  75.  *
  76.  *    Objective C objects are written by sending write: to them, and read by sending read:.
  77.  *    Write methods should look like:
  78.  *    - write: (NXTypedStream *) s {
  79.  *        [super write s];
  80.  *        ...code for writing instance variables defined at this class level ...
  81.  *        };
  82.  *
  83.  *    Read methods should look like:
  84.  *    - read: (NXTypedStream *) s {
  85.  *        [super read s];
  86.  *        ...code for writing instance variables defined at this class level ...
  87.  *        };
  88.  *
  89.  *    For being able to convert old files, it is critical that write: methods always perform [super write: s] before writing any other data.  In a similar fashion, read: methods must always perform [super read: s] before reading any other data.
  90.  *    The current implementation performs write: methods twice, so no side effect should be performed in a write:. 
  91.  *
  92.  *    After reading an object, an awake message is performed, followed by an finishUnarchiving.  The purpose of the awake message is to give a chance to establish invariants within the object, and the purpose of startArchiving: (resp. finishUnarchiving) is to give a chance to replace the object to be written (resp. just read) by some other object.
  93.  *
  94.  */
  95.  
  96. extern void NXWriteType (NXTypedStream *stream, const char *type, const void *data);
  97.     /* data specifies the address of the types to write. */
  98.     
  99. extern void NXReadType (NXTypedStream *stream, const char *type, void *data);
  100.     /* data specifies the address of the types to read.  Expected type is checked against the type actually present on the stream. */
  101.  
  102.  
  103. extern void NXWriteTypes (NXTypedStream *stream, const char *type, ...);
  104.     /* Last arguments specify addresses of values to be written.  It might seem surprising to specify values by address, but this is extremely convenient for copy-paste with NXReadTypes calls.  A more down-to-the-earth cause for this passing of addresses is that values of arbitrary size is not well supported in ANSI C for functions with variable number of arguments. */
  105.     
  106. extern void NXReadTypes (NXTypedStream *stream, const char *type, ...);
  107.     /* Last arguments specify addresses of values to be read.  Expected type is checked against the type actually present on the stream. */
  108.  
  109.  
  110. /***********************************************************************
  111.  *    Conveniences for writing and reading common types of data.
  112.  **********************************************************************/
  113.  
  114. extern void NXWriteArray (NXTypedStream *stream, const char *itemType, int count, const void *data);
  115.     /* Expects data to be an array of count elements of type itemType.  Writes the type specification and the array contents onto the stream.  Equivalent to NXWriteType (stream, "[<count><itemType>]", data).  Example of use: NXWriteArray (stream, "c", 99, data) writes 99 bytes of data. */
  116.     
  117. extern void NXReadArray (NXTypedStream *stream, const char *itemType, int count, void *data);
  118.     /* Expects data to be a previously allocated array of count elements of type itemType. */
  119.  
  120.  
  121. extern void NXWriteObject (NXTypedStream *stream, id object);
  122.     /* Equivalent to NXWriteTypes (stream, "@", &object) */
  123. extern id NXReadObject (NXTypedStream *stream);
  124.     
  125. /***********************************************************************
  126.  *    Writing and reading back pointers.
  127.  **********************************************************************/
  128.  
  129. /*
  130.  *    Backpointers within the saved part of the data structure are stored, while backpointers pointing to outside the saved data structure are not stored.  To specify that a data structure might contain such backpointers, NXWriteRootObject must be called. 
  131.  */
  132.  
  133. extern void NXWriteRootObject (NXTypedStream *stream, id object);
  134.     /* Specifies that a data structure might contain backpointers, and writes it as with NXWriteObject.  This function cannot be called recursively.  The physical stream is flushed after object is written.  The implementation works in 2 passes, which implies that write: methods will be performed twice. */
  135.  
  136. extern void NXWriteObjectReference (NXTypedStream *stream, id object);
  137.     /* Indicates that object is a back pointer, and writes it as with NXWriteObject or writes nil depending on whether object is written by an unconditional NXWriteObject otherwise.  Implies a previous call to NXWriteRootObject. */
  138.  
  139.  
  140. /***********************************************************************
  141.  *    Conveniences for writing and reading files and buffers.
  142.  **********************************************************************/
  143.  
  144. extern NXTypedStream *NXOpenTypedStreamForFile (const char *fileName, int mode);
  145.     /* Opens a file named fileName, and associates it with the NXTypedStream. mode should be NX_READONLY or NX_WRITEONLY.  On closing with NXCloseTypedStream, all buffers and file descriptors are released.  In case of opening error, NULL is returned.  */
  146.  
  147. extern char *NXWriteRootObjectToBuffer (id object, int *length);
  148.     /* Creates a new memory buffer, a corresponding NXTypedStream, writes object using NXWriteRootObject, frees the NXTypedStream, and returns that buffer as well as the number of bytes written.  Use NXFreeObjectBuffer to free buffer. */
  149.  
  150. extern id NXReadObjectFromBuffer (const char *buffer, int length);
  151. extern id NXReadObjectFromBufferWithZone (const char *buffer, int length, NXZone *zone);
  152.     /* Creates a reading NXTypedStream, reads using NXReadObject, frees the NXTypedStream and returns the object.  buffer is not freed. */
  153.  
  154. extern void NXFreeObjectBuffer (char *buffer, int length);
  155.     /* Frees buffer previously created by NXWriteRootObjectToBuffer. */
  156.  
  157.  
  158. /***********************************************************************
  159.  *    Dealing with versions
  160.  **********************************************************************/
  161.  
  162. /*
  163.  *    Three types of versions are supported: typedstream versions (used internally), system versions (accessible when reading a stream), class versions (available for clients).
  164.  *
  165.  */
  166.  
  167. #define NXSYSTEMVERSION082    82
  168. #define NXSYSTEMVERSION083    83
  169. #define NXSYSTEMVERSION090    90
  170. #define NXSYSTEMVERSION0900    900
  171. #define NXSYSTEMVERSION0901    901
  172. #define NXSYSTEMVERSION0905    905
  173. #define NXSYSTEMVERSION0930    930
  174. #define NXSYSTEMVERSION        NXSYSTEMVERSION0930
  175.  
  176. extern int NXSystemVersion (NXTypedStream *stream);
  177.     /* Returns the version used for writing the stream.  Only applicable to reading streams. */
  178.  
  179. extern int NXTypedStreamClassVersion (NXTypedStream *stream, const char *className);
  180. extern BOOL NXTypedStreamIsSwapped (NXTypedStream *stream);
  181.  
  182. /***********************************************************************
  183.  *    Dealing with errors
  184.  **********************************************************************/
  185.  
  186. /* several exceptions can occur; the format of all exceptions raised is a label, a message string and maybe some extra information */
  187.  
  188. #define TYPEDSTREAM_ERROR_RBASE 8000
  189.  
  190. enum TypedstreamErrors {
  191.     TYPEDSTREAM_CALLER_ERROR = TYPEDSTREAM_ERROR_RBASE,
  192.     TYPEDSTREAM_FILE_INCONSISTENCY,
  193.     TYPEDSTREAM_CLASS_ERROR,
  194.     TYPEDSTREAM_TYPE_DESCRIPTOR_ERROR,
  195.     TYPEDSTREAM_WRITE_REFERENCE_ERROR,
  196.     TYPEDSTREAM_INTERNAL_ERROR
  197. };
  198.  
  199. #endif /* _OBJC_TYPEDSTREAM_H_ */
  200.